#include "zObjectMesh.hpp"

namespace zzz{
bool zObjectMesh::LoadFromMemory(istringstream &iss, const string &path)
{
  ObjMesh *o=(ObjMesh*)m_obj;
  float trans[3],rot[4],scaleto;
  string tmp,filename;
  bool normalize=true,createvbo=true,calnormal=false,translate=false,rotate=false,scale=false;
  while(true)
  {
    iss>>tmp;
    if (iss.fail()) break;
    ToLow(tmp);
    if (tmp=="f" || tmp=="file" || tmp=="filename")
    {
      iss>>tmp;
      filename=PathFile(path,tmp);
    }
    else if (tmp=="e" || tmp=="emi" || tmp=="emission" || tmp=="ems")
    {
      iss>>o->m_mat_emi[0]>>o->m_mat_emi[1]>>o->m_mat_emi[2]>>o->m_mat_emi[3];
    }
    else if (tmp=="a" || tmp=="amb" || tmp=="ambient" || tmp=="abt")
    {
      iss>>o->m_mat_amb[0]>>o->m_mat_amb[1]>>o->m_mat_amb[2]>>o->m_mat_amb[3];
    }
    else if (tmp=="d" || tmp=="dif" || tmp=="diffuse" || tmp=="dfs")
    {
      iss>>o->m_mat_dif[0]>>o->m_mat_dif[1]>>o->m_mat_dif[2]>>o->m_mat_dif[3];
    }
    else if (tmp=="s" || tmp=="spe" || tmp=="specular" || tmp=="spc")
    {
      iss>>o->m_mat_spe[0]>>o->m_mat_spe[1]>>o->m_mat_spe[2]>>o->m_mat_spe[3];
    }
    else if (tmp=="i" || tmp=="shi" || tmp=="shininess" || tmp=="shn")
    {
      iss>>o->m_mat_shi;
    }
    else if (tmp=="normalize")
    {
      iss>>tmp;
      ToLow(tmp);
      if (tmp=="true" || tmp=="t" || tmp=="1") normalize=true;
      else if (tmp=="false" || tmp=="f" || tmp=="0") normalize=false;
      else 
      {
        printf("UNKNOWN PARAMETER: %s\n",tmp.c_str());
        return false;
      }
    }
    else if (tmp=="createvbo")
    {
      iss>>tmp;
      ToLow(tmp);
      if (tmp=="true" || tmp=="t" || tmp=="1") createvbo=true;
      else if (tmp=="false" || tmp=="f" || tmp=="0") createvbo=false;
      else 
      {
        printf("UNKNOWN PARAMETER: %s\n",tmp.c_str());
        return false;
      }
    }
    else if (tmp=="calnormal")
    {
      iss>>tmp;
      ToLow(tmp);
      if (tmp=="true" || tmp=="t" || tmp=="1") calnormal=true;
      else if (tmp=="false" || tmp=="f" || tmp=="0") calnormal=false;
      else 
      {
        printf("UNKNOWN PARAMETER: %s\n",tmp.c_str());
        return false;
      }
    }
    else if (tmp=="translate" || tmp=="t")
    {
      iss>>trans[0]>>trans[1]>>trans[2];
      translate=true;
    }
    else if (tmp=="rotate" || tmp=="r")
    {
      iss>>rot[0]>>rot[1]>>rot[2]>>rot[3];
      rotate=true;
    }
    else if (tmp=="scale")
    {
      iss>>scaleto;
      scale=true;
    }
    else
    {
      printf("UNKNOWN PARAMETER: %s\n",tmp.c_str());
      return false;
    }
  }
  printf("Load obj file: %s\n",filename.c_str());
  if (!o->LoadFromFile(filename.c_str()))
  {
    printf("ERROR: Load Obj: %s\n",filename.c_str());
    return false;
  }
  if (normalize) o->Normalize();
  if (scale) o->Scale(scaleto);
  if (rotate) o->Rotate(rot[0],rot[1],rot[2],rot[3]);
  if (translate) o->Translate(trans[0],trans[1],trans[2]);
  if (createvbo) o->CreateVBO();
  if (calnormal) o->CalNormal();
  return true;
}
bool zObjectMesh::Do(const string &cmd1, const vector<zParam*> &param, zParam *ret)
{
  ObjMesh *obj=(ObjMesh*)m_obj;
  string cmd=ToLow_copy(cmd1);
  if (cmd=="draw")
    obj->Draw();
  else if (cmd=="drawvbo")
    obj->DrawVBO();
  else if (cmd=="drawelement")
    obj->DrawElement();
  else if (cmd=="scale")
  {
    double *d0=zparam_cast<double>(param[0]);
    obj->Scale(*d0);
  }
  else if (cmd=="translate")
  {
    double *d0=zparam_cast<double>(param[0]);
    double *d1=zparam_cast<double>(param[1]);
    double *d2=zparam_cast<double>(param[2]);
    obj->Translate(*d0,*d1,*d2);
  }
  else if (cmd=="rotate")
  {
    double *d0=zparam_cast<double>(param[0]);
    double *d1=zparam_cast<double>(param[1]);
    double *d2=zparam_cast<double>(param[2]);
    double *d3=zparam_cast<double>(param[3]);
    obj->Rotate(*d0,*d1,*d2,*d3);
  }
  else return false;
  return true;
}

bool zObjectMesh::IsTrue()
{
  return true;
}

string zObjectMesh::ToString()
{
  return string("Texture2D");
}


}